package org.molamil.acto.props {
	import flexunit.framework.TestCase;
	import org.molamil.acto.core.parsers.ParserError;	
	
	/**
	 * TODO: Add updated tests to cover ParsedProps and PropContext.
	 * @author Jorge Hernandez
	 */
	public class NativePropsParserTest extends TestCase {
		
		
		// PROPERTIES
		
		private var instance:NativePropsParser;
		
		
		// CONSTRUCTOR
		
		public function NativePropsParserTest(methodName:String = null) {
			super(methodName);
		}
		
		
		// PUBLIC METHODS
		
		override public function setUp():void {
			instance = new NativePropsParser();
		}
		
		override public function tearDown():void {
			instance = null;
		}
		
		public function testParseFormat():void {
			
			// Props and prop.
			var xmlPropsAndProp:XML = <dummy>
				<props>
					<prop name="name" value="Jorge" />
				</props>
				<prop name="lastname" value="Hernandez" />
			</dummy>;
			
			try {
				instance.parse(xmlPropsAndProp);
				// Now throwing events instead of erros.
				//fail("'props' and 'prop' in the conf should fail");
			} catch (e:ParserError) {}
			
			// ...
			
			// More than 1 props.
			var xmlMoreProps:XML = <dummy>
				<props>
					<prop name="name" value="Jorge" />
				</props>
				<props>
					<prop name="lastname" value="Hernandez" />
				</props>
			</dummy>;
			
			try {
				instance.parse(xmlMoreProps);
				// Now throwing events instead of erros.
				//fail("More than 1 'props' should fail");
			} catch (e:ParserError) {}
			
			// ...
			
			// Props and item.
			var xmlPropsAndItems:XML = <dummy>
				<props>
					<prop name="name" value="Jorge" />
				</props>
				<item>pizza</item>
			</dummy>;
			
			try {
				instance.parse(xmlPropsAndItems);
				// Now throwing events instead of erros.
				//fail("'props' and 'item' should fail");
			} catch (e:ParserError) {}
			
			// ...
			
			// Prop and item.
			var xmlPropAndItem:XML = <dummy>
				<prop name="name" value="Jorge" />
				<item>pizza</item>
			</dummy>;
			
			try {
				instance.parse(xmlPropAndItem);
				// Now throwing events instead of erros.
				//fail("'prop' and 'item' should fail");
			} catch (e:ParserError) {}
			
		}
			
		//XXX: Simple props are deprecated.
//		public function testParseSimple():void {
//			
//			var o:*;
//			var xml:XML;
//			
//
//			// Standard string.
//			xml = <prop>Jorge</prop>;
//			
//			o = instance.parse(xml).props;
//			
//			assertNotNull("o is not null", o);
//			assertEquals("o contains Jorge", o, "Jorge");
//			assertTrue("o is a String", o is String);
//			
//			// ...
//			
//			// Standard number.
//			xml = <prop name="n">150.50</prop>;
//			
//			o = instance.parse(xml);
//			
//			assertNotNull("o is not null", o);
//			assertEquals("o contains 150.50", o, 150.50);
//			assertTrue("o is a Number", o is Number);
//			
//			// ...
//			
//			// Standard date.
//			xml = <prop>2008-08-07</prop>;
//			
//			o = instance.parse(xml);
//			
//			assertNotNull("o is not null", o);
//			assertEquals("o contains the set date", (o as Date).getTime(), new Date(2008, 7, 7).getTime());
//			assertTrue("o is a Date", o is Date);
//			
//		}
		
		public function testParseStandard():void {
			
			var o:*;
			var xml:XML;
			
			// Standard string.
			xml = <props>
				<prop name="name" value="Jorge" />
			</props>;
			
			o = instance.parse(xml).props;
			
			assertNotNull("o is not null", o);
			assertNotNull("o contains name", o["name"]);
			assertEquals("o.name has value as Jorge", o["name"], "Jorge");
			
			// Standard assorted types.
			xml = <props>
				<prop name="b" value="false" />
				<prop name="n">1</prop>
				<prop name="d">2008-08-07</prop>
				<prop name="s">Jorge</prop>
				<prop name="nothing"/>
			</props>;
			
			o = instance.parse(xml).props;
			
			assertNotNull("o is not null", o);
			assertTrue("o is an Object", o is Object);
			assertEquals("o.b has value as false", o["b"], false);
			assertEquals("o.n has value as 1", o["n"], 1);
			assertEquals("o.d has value as 2008-08-07 (Date)", (o["d"] as Date), new Date(2008, 7, 7).getTime());
			assertEquals("o.s has value as 'Jorge'", o["s"], "Jorge");
			//XXX: Should it be null?
//			assertEquals("o.nothing has value as null", o["nothing"], null);
			assertTrue("o.b is a Boolean", o["b"] is Boolean);
			assertTrue("o.n is an Number", o["n"] is Number);
			assertTrue("o.d is an Date", o["d"] is Date);
			assertTrue("o.s is an String", o["s"] is String);
			assertTrue("o.nothing is not undefined", o["nothing"] !== undefined);
			
		}
		
		public function testParseGoItLoopVideo():void {
			
			var o:*;
			var xml:XML;
			
			// Taken from www.goitloop.com
			include "testParseGoItLoopVideo.txt"
			
			o = instance.parse(xml).props;
			
			assertTrue("o is an Object", o is Object);
			assertTrue("o.videoLenght has right number value", o["videoLenght"] === 40560);
			assertTrue("o.videoFile has right String value", o["videoFile"] === "flv/01_intro_NEW_C1.flv");
			assertTrue("o.events is an Array", o["events"] is Array);
			assertEquals("o.events has 9 elements", (o["events"] as Array).length, 9);
			assertTrue("o.events[0] is an Object", o["events"][0] is Object);
			assertTrue("o.events[0].time has the right number value", o["events"][0]["time"] === 7500);
			assertTrue("o.events[0].event has the String value", o["events"][0]["event"] === "showPartners");
			assertTrue("o.events[8] is an Object", o["events"][8] is Object);
			assertTrue("o.events[8].time has the right number value", o["events"][8]["time"] === 36000);
			assertTrue("o.events[8].event has the String value", o["events"][8]["event"] === "showFlowers");
			
		}
		
		public function testParseGoItGreenCalculator():void {
			
			var o:*;
			var xml:XML;
			
			// Taken from www.goitgreen.com
			include "testParseGoItGreenCalculator.txt"
			
			o = instance.parse(xml).props;
			
			assertTrue("o is an Object", o is Object);
			assertTrue("o.title", o["title"] === "Calculator");
			assertTrue("o.gateway.guideTitle", o["gateway"]["guideTitle"] === "Quick Green Focus Guide");
			assertTrue("o.guide.cLabel is an Arary", o["guide"]["cLabel"] is Array);
			assertEquals("o.guide.cLabel has 5 elements", (o["guide"]["cLabel"] as Array).length, 5);
			assertTrue("o.guide.cLabel[2]", (o["guide"]["cLabel"] as Array)[2] === "Sometimes");
			assertTrue("o.guide.block.[1].questions[0].model", 
				((o["guide"]["block"] as Array)[1]["questions"] as Array)[0]["model"] === "radiolist");
			assertTrue("o.calculator.savingItems[2].title", (o["calculator"]["savingItems"] as Array)[2]["title"] 
				=== "CO2:");
			
		}
		
		public function testParseCokeMp3():void {
			
			var o:*;
			var xml:XML;
			
			// Taken from www.coke.dk
			include "testParseCokeMp3.txt"
			
			o = instance.parse(xml).props;
			
			assertTrue("o is an Object", o is Object);
			assertTrue("o.mp3s is an Arary", o["mp3s"] is Array);
			assertEquals("o.mp3s has 9 elements", (o["mp3s"] as Array).length, 9);
			assertTrue("o.mp3s[7].name", (o["mp3s"] as Array)[7]["name"] === "CLASSICAL");
			assertTrue("o.mp3s[7].description", (o["mp3s"] as Array)[7]["description"]
				=== "Always Coca-Cola®");
			
		}
		
	}
	
}
